#!/bin/bash

# 设置命名空间和默认备份目录
BACKUP_DIR="/opt/cnpg_pvbak_$(date +%Y%m%d%H%M%S)"  # 默认备份目录
KUBE_USER=$(whoami)    # 获取当前用户

# 函数：检查kubectl访问权限
check_kubectl_access() {
    if ! kubectl get ns >/dev/null 2>&1; then
        echo "错误: 当前用户($KUBE_USER)无法访问Kubernetes集群"
        echo "请确保:"
        echo "1. kubectl已正确配置"
        echo "2. 当前用户有访问集群的权限"
        echo "3. 如果使用kubeconfig，请确认环境变量KUBECONFIG已设置"
        exit 1
    fi
}

# 函数：获取主库名称
get_primary_cluster() {
    echo "正在查询PostgreSQL集群的主库信息..."
    PRIMARY_NAME=$(kubectl get pod -n pg-system -l 'cnpg.io/instanceRole=primary' -o jsonpath='{.items[0].metadata.name}' 2>/dev/null)
    
    if [ -z "$PRIMARY_NAME" ]; then
        echo "错误: 无法获取PostgreSQL集群的主库信息"
        exit 1
    fi
    
    echo "找到主库: $PRIMARY_NAME"
}

# 函数：获取PV信息
get_pv_info() {
    echo "正在查询PV信息..."
    PV_NAME=$(kubectl get pvc $PRIMARY_NAME -n pg-system -o jsonpath='{.spec.volumeName}' 2>/dev/null)
    
    if [ -z "$PV_NAME" ]; then
        echo "错误: 无法获取PV名称"
        exit 1
    fi
    
    echo "找到PV: $PV_NAME"
    
    PV_PATH=$(kubectl get pv $PV_NAME -o jsonpath='{.spec.local.path}')
    if [ -z "$PV_PATH" ]; then
        echo "错误: 无法解析PV存储路径"
        exit 1
    fi
    
    NODE_NAME=$(kubectl get pv $PV_NAME -o jsonpath='{.spec.nodeAffinity.required.nodeSelectorTerms[0].matchExpressions[0].values[0]}')
    if [ -z "$NODE_NAME" ]; then
        echo "错误: 无法解析PV所在节点名称"
        exit 1
    fi

    # 获取节点IP地址（优先InternalIP，其次ExternalIP，最后回退到节点名称）
    NODE_IP=$(kubectl get node $NODE_NAME -o jsonpath='{.status.addresses[?(@.type=="InternalIP")].address}')
    if [ -z "$NODE_IP" ]; then
        NODE_IP=$(kubectl get node $NODE_NAME -o jsonpath='{.status.addresses[?(@.type=="ExternalIP")].address}')
        [ -z "$NODE_IP" ] && NODE_IP=$NODE_NAME
    fi
    
    echo "PV所在节点: $NODE_NAME (IP: $NODE_IP)"
    echo "PV存储路径: $PV_PATH"
}

# 函数：生成远程执行命令
generate_remote_command() {
    local NODE_IP=$1
    local NODE_NAME=$2
    local PV_PATH=$3
    local BACKUP_DIR=$4
    
    echo "请在节点 $NODE_NAME (IP: $NODE_IP) 上执行以下步骤:"
    echo "----------------------------------------------------------------------------------------------------"
    echo "1. 使用SSH登录到节点:"
    echo "   ssh $NODE_IP"
    echo ""
    echo "2. 执行备份命令(需要sudo权限):"
    echo ""
    echo "   sudo bash -c '"
    echo "     echo \"验证目录是否存在...\";"
    echo "     if [ ! -d \"$PV_PATH/pgdata\" ]; then"
    echo "       echo \"错误: 在 $PV_PATH 下找不到pgdata目录\";"
    echo "       exit 1;"
    echo "     fi;"
    echo "     echo \"创建备份目录...\";"
    echo "     mkdir -p \"$BACKUP_DIR\" || exit 1;"
    echo "     echo \"开始备份数据(可能需要较长时间)...\";"
    echo "     cp -a \"$PV_PATH/pgdata\" \"$BACKUP_DIR/\" || { echo \"备份失败\"; exit 1; };"
    echo "     echo \"备份完成！备份目录内容:\";"
    echo "     ls -l \"$BACKUP_DIR/pgdata\";"
    echo "     echo \"备份总大小:\";"
    echo "     du -sh \"$BACKUP_DIR/pgdata\""
    echo "   '"
    echo ""
    echo "----------------------------------------------------------------------------------------------------"
}

# 主程序
check_kubectl_access
get_primary_cluster
get_pv_info

# 检查当前节点是否是PV所在节点
CURRENT_NODE=$(hostname)
if [ "$CURRENT_NODE" != "$NODE_NAME" ]; then
    echo "当前节点 $CURRENT_NODE 不是PV所在节点 $NODE_NAME"
    generate_remote_command "$NODE_IP" "$NODE_NAME" "$PV_PATH" "$BACKUP_DIR"
    exit 0
fi

# 如果当前节点是PV所在节点
echo "当前节点是PV所在节点"
if [ ! -d "$PV_PATH/pgdata" ]; then
    echo "错误: 在 $PV_PATH 下找不到pgdata目录"
    exit 1
fi

echo "准备备份PV目录..."
read -p "是否要备份此目录到 $BACKUP_DIR? (y/n) " BACKUP_CHOICE
if [[ $BACKUP_CHOICE =~ ^[Yy]$ ]]; then
    sudo bash -c "
        echo '创建备份目录...';
        mkdir -p \"$BACKUP_DIR\" || exit 1;
        echo '开始备份数据(可能需要较长时间)...';
        cp -a \"$PV_PATH/pgdata\" \"$BACKUP_DIR/\" || { echo '备份失败'; exit 1; };
        echo '备份完成！备份目录内容:';
        ls -l \"$BACKUP_DIR/pgdata\";
        echo '备份总大小:';
        du -sh \"$BACKUP_DIR/pgdata\"
    "
fi

echo "脚本执行完成"